package com.pcbly.web.action.jbpm;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.pcbly.web.action.BaseAction;
import com.pcbly.web.business.jbpm.JbpmService;
import com.pcbly.web.components.utils.random.GUID;

import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.model.ActivityCoordinates;

@SuppressWarnings("unchecked")
public class JbpmProcessAction extends BaseAction {
	/**
	 * 
	 */
	private static final long serialVersionUID = -6578437597605597150L;

	private JbpmService jbpmService;

	private File upload;

	private List<ProcessDefinition> processDefinitions;

	private List<ProcessInstance> processInstances;

	private String fileName;

	private String contentType;

	private String pdId;

	private String result;

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public String getPdId() {
		return pdId;
	}

	public void setPdId(String pdId) {
		this.pdId = pdId;
	}

	public List<ProcessInstance> getProcessInstances() {
		return processInstances;
	}

	public void setProcessInstances(List<ProcessInstance> processInstances) {
		this.processInstances = processInstances;
	}

	public List<ProcessDefinition> getProcessDefinitions() {
		return processDefinitions;
	}

	public void setProcessDefinitions(List<ProcessDefinition> processDefinitions) {
		this.processDefinitions = processDefinitions;
	}

	public String instance() throws Exception {
		processInstances = jbpmService.getProcessInstances(pdId);
		logDBAction("instance", "show Process Instance:" + pdId);
		return SUCCESS;
	}

	public String suspendedInstances() throws Exception {
		processInstances = jbpmService.getSuspendedProcessInstances();
		logDBAction("suspendedInstances", "suspended Process Instance:");
		return SUCCESS;
	}

	public String suspendedInstance() throws Exception {
		jbpmService.suspendProcessInstance(getId());
		logDBAction("suspendedInstance", "suspended Process Instance:"
				+ getId());
		return SUCCESS;
	}

	public String resumeInstance() throws Exception {
		jbpmService.resumeProcessInstance(getId());
		logDBAction("resumeInstance", "resume Process Instance:" + getId());
		return SUCCESS;
	}

	public String endInstance() throws Exception {
		jbpmService.endProcessInstance(getId());
		logDBAction("endInstance", "end Process Instance:" + getId());
		return SUCCESS;
	}

	public String reportOverallActivity() throws Exception {
		result = jbpmService.reportOverallActivity();
		logDBAction("reportOverallActivity", "show Overall Activity Process :"
				+ result);
		return SUCCESS;
	}

	public String reportSummary() throws Exception {
		result = jbpmService.reportOverallActivity();
		logDBAction("reportSummary", "show Summary Process :" + result);
		return SUCCESS;
	}

	public String reportMostActive() throws Exception {
		result = jbpmService.reportMostActiveProcess();
		logDBAction("reportMostActive", "show Most Active Process :" + result);
		return SUCCESS;
	}

	public String detail() throws Exception {
		ProcessDefinition processDefinition = jbpmService
				.getProcessDefinitionByProcessInstanceId(getId());
		ActivityCoordinates ac = jbpmService.getActivityCoordinates(getId());
		logDBAction("detail", "show detail Process :" + getId());
		HttpServletRequest request = getRequest();
		StringBuilder sb = new StringBuilder();
		sb.append("<script type=\"text/javascript\" src=\"");
		sb.append(request.getContextPath());
		sb.append("/scripts/replay.js\"></script>");
		sb.append("<img style=\"position:absolute;left:0px;top:0px;\" ");
		sb.append(" src=\"");
		sb.append(request.getContextPath());
		sb.append("/index.crm?id=");
		sb.append(processDefinition.getId());
		sb.append("\"><div style=\"position:absolute;left:");
		sb.append(ac.getX());
		sb.append("px;top:");
		sb.append(ac.getY());
		sb.append("px;width:");
		sb.append(ac.getWidth());
		sb.append("px;height:");
		sb.append(ac.getHeight());
		sb.append("px;border:1px solid red;background-color:green;");
		sb.append("filter:Alpha(opacity=50);opacity:0.5;\"></div>");
		sb.append("<script type=\"text/javascript\">");
		sb.append("var array = [");
		List<ActivityCoordinates> acs = jbpmService
				.getHistoryActivities(getId());
		for (ActivityCoordinates acm : acs) {
			sb.append("{x:");
			sb.append(acm.getX());
			sb.append(",y:");
			sb.append(acm.getY());
			sb.append(",w:");
			sb.append(acm.getWidth());
			sb.append(",h:");
			sb.append(acm.getHeight());
			sb.append("},");
		}
		if (sb.charAt(sb.length() - 1) == ',') {
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append("];");
		sb.append("</script>");
		return SUCCESS;
	}

	public String removeInstance() throws Exception {
		jbpmService.removeProcessInstance(getId());
		logDBAction("removeInstance", "remove Process Instance  :" + getId());
		return SUCCESS;
	}

	public String index() throws Exception {
		if (log.isDebugEnabled()) {
			log.debug("login index........");
		}
		try {
			logDBAction("index", "show index  process");
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return SUCCESS;
	}

	public String save() throws Exception {
		if (log.isDebugEnabled()) {
			log.debug("login save........");
		}
		try {
			if (fileName == null || "".equals(fileName)) {
				addActionError(getText("deploy.errorNoFile"));
				return SUCCESS;
			}
			String fileNewName = "F" + ((new GUID()).toString());

			fileNewName = fileNewName
					+ fileName.substring(fileName.lastIndexOf("."), fileName
							.length());
			String uploadDir = getServletContext().getRealPath("/upload");
			String path = uploadDir;
			OutputStream fos = new FileOutputStream(path + "\\" + fileNewName);
			InputStream fis = new FileInputStream(upload);
			int len = 0;
			byte[] buffer = new byte[1024];
			StringBuffer sb=new StringBuffer();
			while ((len = fis.read(buffer)) > 0) {
				fos.write(buffer, 0, len);
				String read=new String(buffer,0,len);
				read=new String(read.getBytes(), "UTF-8");
				sb.append(read); 
				
			}
			if (contentType.indexOf("xml") > 0) {
				jbpmService.deployXml(fileName, sb);
			} else if (contentType.indexOf("zip") > 0) {
				jbpmService.deployZip(fis);
			}
			if (fos != null)
				fos.close();
			if (fis != null)
				fis.close();
			addActionMessage(getText("deploy.success"));
			logDBAction("save", "deploy  process");
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return SUCCESS;
	}

	public String showLastest() throws Exception {
		processDefinitions = jbpmService.getLatestProcessDefinitions();
		logDBAction("showLastest", "show lastest processes");
		return SUCCESS;
	}

	public String suspendeds() throws Exception {
		processDefinitions = jbpmService.getSuspendedProcessDefinitions();
		logDBAction("suspendeds", "suspended  processes");
		return SUCCESS;
	}

	public String suspended() throws Exception {
		jbpmService.suspendProcessDefinitionById(getId());
		logDBAction("suspended", "suspended  process:" + getId());
		return SUCCESS;
	}

	public String resume() throws Exception {
		jbpmService.resumeProcessDefinitionById(getId());
		logDBAction("resume", "resume  process:" + getId());
		return SUCCESS;
	}

	public String remove() throws Exception {
		jbpmService.removeProcessDefinitionById(getId());
		logDBAction("remove", "remove  process:" + getId());
		return SUCCESS;
	}

	public void setJbpmService(JbpmService jbpmService) {
		this.jbpmService = jbpmService;
	}

	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getUploadContentType() {
		return contentType;
	}

	public void setUploadContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getUploadFileName() {
		return fileName;
	}

	public void setUploadFileName(String fileName) {
		this.fileName = fileName;
	}
}
